package com.yh.interceptor;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yh.anno.LoginInterceptor;
import com.yh.utils.Constants;
import com.yh.vo.LoginVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.util.ObjectUtils;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * 拦截登录请求
 *
 * @author yuhuan
 * @date 2022/01/13
 */
public class LoginRequestInterceptor implements HandlerInterceptor {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException, ServletException {
        // 如果方法或者类上标记了登录拦截注解就进行拦截，否则就放行
        if (IsInterceptorToPreHandle.isInterceptor(handler, LoginInterceptor.class)) {
            // 获取登录信息
            String screenData = request.getReader().readLine();
            // 没有接收到登录信息，直接放行到请求入口
            if (ObjectUtils.isEmpty(screenData)) {
                return true;
            }
            LoginVO loginVo = objectMapper.readValue(screenData, LoginVO.class);
            // 处理普通用户登录
            if (loginVo.getIdentity() == Constants.LoginData.USER_ROLE) {
                saveLoginVoToRedis(loginVo);
                // 将请求放行到普通用户的登录处理器
                request.getRequestDispatcher("/api/login/user/server").forward(request, response);
                return false;
            }
            // 处理开发者登录
            if (loginVo.getIdentity() == Constants.LoginData.DEVELOPER_ROLE) {
                saveLoginVoToRedis(loginVo);
                // 将请求放行到开发者的登录处理器
                request.getRequestDispatcher("/api/login/developer/server").forward(request, response);
                return false;
            }
            // 其他登录请求均放行到请求入口处统一处理
            return true;
        } else {
            return true;
        }
    }

    /**
     * 将登录信息保存到缓存中
     */
    private void saveLoginVoToRedis(LoginVO loginVo) {
        // 获取字符串类型的操作模板
        ValueOperations operations = redisTemplate.opsForValue();
        try {
            // 将用户数据序列化
            String loginVoJson = objectMapper.writeValueAsString(loginVo);
            // 将信息缓存到redis并设置缓存的过期时间
            operations.set(Constants.LoginData.LOGIN_DATA_PREFIX_KEY, loginVoJson, 10, TimeUnit.MINUTES);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }
}
